using System;
using System.IO;
using System.Reflection;

namespace CoverageRunner
{
    public class CoverageGenerator
    {
        private readonly string vstsCoverageOutputFile;
        private readonly UnitTestRunner testRunner;
        private readonly CoverageReportCreator reportCreator;

        public CoverageGenerator(string vstsCoverageOutputFile, UnitTestRunner testRunner, CoverageReportCreator reportCreator)
        {
            this.vstsCoverageOutputFile = vstsCoverageOutputFile;
            this.testRunner = testRunner;
            this.reportCreator = reportCreator;
        }

        public void Execute()
        {
            if (AllAssemblyDependenciesExist())
            {
                using (new ProfilerRunner())
                using (new CoverageRunner(vstsCoverageOutputFile))
                {
                    string output = testRunner.Execute();
                    Console.WriteLine(output);
                    if (testRunner.ExitCode != 0)
                        throw new ApplicationException("Unable to successfully execture the test runner");
                }
                string reportOutput = reportCreator.Create();
                Console.WriteLine(reportOutput);
            }
        }

        /// <summary>
        /// Checks the assembly dependencies exist. 
        /// </summary>
        /// <remarks>
        /// As the Profiler uses old fashioned DLLs we cannot put these as
        /// project dependencies, and therefore just do a check for their existence in the applciation directory.
        /// Without this check a weird File Not Found exception will be thrown with an HRESULT.
        /// </remarks>
        private static bool AllAssemblyDependenciesExist()
        {
            bool valid = true;

            if (!CheckForExistenceOf("symsrv.dll")) valid = false;
            if (!CheckForExistenceOf("VSPerfAnalysis.dll")) valid = false;
            if (!CheckForExistenceOf("VSPerfData.dll")) valid = false;
            if (!CheckForExistenceOf("VSPerfPresentation.dll")) valid = false;
            if (!CheckForExistenceOf("VSPerfReader.dll")) valid = false;
            if (!CheckForExistenceOf("vspmsg.dll")) valid = false;

            if (!valid)
                Console.WriteLine(
                    @"The missing assemblies can usually be found in the Team Tools/Performance directory (e.g. C:\Program Files\Microsoft Visual Studio 9.0\Team Tools\Performance Tools)");
            
            return valid;
        }

        private static bool CheckForExistenceOf(string assembly)
        {
           if (File.Exists(assembly))
                return true;

            Console.WriteLine("{0} is a required dependency and must be copied to the application directory", assembly);
            return false;
        }
    }
}